# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-07-15 23:32
# File     : formatters.py
# Project  : dynamic-portfolio-optimizer
# Desc     :
# src/utils/formatters.py
import pandas as pd
from typing import Dict, Any, List
from datetime import datetime


class DataFormatter:
    """数据格式化器"""

    @staticmethod
    def format_price_data(df: pd.DataFrame) -> pd.DataFrame:
        """格式化价格数据"""
        if df.empty:
            return df

        df = df.copy()

        # 确保数值列为float类型
        numeric_columns = ['open', 'high', 'low', 'close', 'volume', 'adj_close']
        for col in numeric_columns:
            if col in df.columns:
                df[col] = pd.to_numeric(df[col], errors='coerce')

        # 四舍五入价格到2位小数
        price_columns = ['open', 'high', 'low', 'close', 'adj_close']
        for col in price_columns:
            if col in df.columns:
                df[col] = df[col].round(2)

        # 成交量取整
        if 'volume' in df.columns:
            df['volume'] = df['volume'].fillna(0).astype(int)

        # 确保索引为DatetimeIndex
        if not isinstance(df.index, pd.DatetimeIndex):
            if 'timestamp' in df.columns:
                df = df.set_index('timestamp')
            elif 'date' in df.columns:
                df = df.set_index('date')

        # 排序
        df = df.sort_index()

        return df

    @staticmethod
    def format_fundamentals(data: Dict[str, Any]) -> Dict[str, Any]:
        """格式化基本面数据"""
        if not data:
            return data

        formatted = data.copy()

        # 格式化数值字段
        numeric_fields = [
            'market_cap', 'pe_ratio', 'pb_ratio', 'dividend_yield',
            'beta', 'eps', 'revenue', 'gross_margin', 'profit_margin',
            'roe', 'roa', 'debt_to_equity'
        ]

        for field in numeric_fields:
            if field in formatted:
                try:
                    value = float(formatted[field])
                    if field in ['market_cap', 'revenue']:
                        # 大数值保留整数
                        formatted[field] = int(value) if not pd.isna(value) else 0
                    elif field in ['dividend_yield', 'gross_margin', 'profit_margin']:
                        # 百分比保留3位小数
                        formatted[field] = round(value, 3) if not pd.isna(value) else 0
                    else:
                        # 其他比率保留2位小数
                        formatted[field] = round(value, 2) if not pd.isna(value) else 0
                except (ValueError, TypeError):
                    formatted[field] = 0

        # 清理字符串字段
        string_fields = ['company_name', 'sector', 'industry', 'description']
        for field in string_fields:
            if field in formatted:
                formatted[field] = str(formatted[field]).strip()

        return formatted

    @staticmethod
    def format_news(news_list: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """格式化新闻数据"""
        formatted_news = []

        for news in news_list:
            formatted = news.copy()

            # 清理标题和摘要
            if 'title' in formatted:
                formatted['title'] = str(formatted['title']).strip()

            if 'summary' in formatted:
                summary = str(formatted['summary']).strip()
                # 限制摘要长度
                if len(summary) > 500:
                    summary = summary[:497] + "..."
                formatted['summary'] = summary

            # 确保时间格式
            if 'published_at' in formatted:
                if isinstance(formatted['published_at'], str):
                    try:
                        formatted['published_at'] = pd.to_datetime(formatted['published_at'])
                    except:
                        formatted['published_at'] = datetime.now()

            # 验证URL
            if 'url' in formatted:
                url = str(formatted['url']).strip()
                if not (url.startswith('http://') or url.startswith('https://')):
                    formatted['url'] = ''

            formatted_news.append(formatted)

        return formatted_news

    @staticmethod
    def to_json_serializable(obj: Any) -> Any:
        """转换为JSON可序列化对象"""
        if isinstance(obj, pd.DataFrame):
            return obj.to_dict('records')
        elif isinstance(obj, pd.Series):
            return obj.to_dict()
        elif isinstance(obj, datetime):
            return obj.isoformat()
        elif isinstance(obj, pd.Timestamp):
            return obj.isoformat()
        elif isinstance(obj, dict):
            return {k: DataFormatter.to_json_serializable(v) for k, v in obj.items()}
        elif isinstance(obj, list):
            return [DataFormatter.to_json_serializable(item) for item in obj]
        else:
            return obj
